
#include <BSize>
#include <BFont>
#include <BWidget>
#include <BStyle>

#include "member_BButton.h"

using namespace BWE;

member_BButton::member_BButton(BButton* button)
{
	boss = button;
	alignment.ia_form = Form_None;
	alignment.ia_align = Align_Center;
	alignment.ia_spacing = 1;
	graph = Graph_None;
	checkable = false;
	checked = false;
	shortcutVisible = true;

	dirty = true;
	pressed = false;
}
member_BButton::~member_BButton()
{

}

BImage* member_BButton::realImage()
{
	if (image.valid())
		return image;
	if (action)
		return action->image();
	return 0;
}
BIcon* member_BButton::realIcon()
{
	if (BIcon* icon = boss->icon())
		return icon;
	if (action)
		return action->icon();
	if (menu)
		return menu->icon();
	return 0;
}
Graph member_BButton::realGraph()
{
	if (graph)
		return graph;
	if (action)
		return action->graph();
	return Graph_None;
}
bool member_BButton::imageShown()
{
	if (alignment.ia_form > Form_IconAlone)
		return true;
	bool hasImage = realIcon() || realImage() || realGraph();
	if (alignment.ia_form == Form_IconAlone)
	{
		if (!hasImage)
			return false;
		return true;
	}
	if (alignment.ia_form == Form_TextAlone)
	{
		if (alignment.ia_textSize.empty() && hasImage)
			return true;
		return false;
	}
	return hasImage;
}
void member_BButton::freshRects()
{
	const BStyle* style = boss->realStyle();
	if (style)
	{
		if (t_text.empty())
		{
			if (text.size())
				style->translate(text, t_text);
			else if (action)
				style->translate(action->text(), t_text);
			else if (menu)
				style->translate(menu->title(), t_text);
		}
		if (t_text_checked.empty() && checkedText.size())
			style->translate(checkedText, t_text_checked);
		if (t_text_uncheck.empty() && uncheckText.size())
			style->translate(uncheckText, t_text_uncheck);
	}
	alignment.ia_textSize.reset();
	const BFont* font = style->font();
	if (font)
	{
		if (t_text.size())
			alignment.ia_textSize = font->textSize(t_text);
		else if (text.size())
			alignment.ia_textSize = font->textSize(text);
		else if (action)
			alignment.ia_textSize = font->textSize(action->text());
		else if (menu)
			alignment.ia_textSize = font->textSize(menu->title());

		if (t_text_checked.size())
			alignment.ia_textSize.expand(font->textSize(t_text_checked));
		else
			alignment.ia_textSize.expand(font->textSize(checkedText));

		if (t_text_uncheck.size())
			alignment.ia_textSize.expand(font->textSize(t_text_uncheck));
		else
			alignment.ia_textSize.expand(font->textSize(uncheckText));
	}
	if (this->imageShown())
	{
		BSize realIconSize = iconSize;
		const BImage* realImage = image;
		if (BIcon* icon = boss->icon())
			realImage = icon->image();
		if (realImage)
		{
			if (realIconSize.width() < 0)
				realIconSize.width() = realImage->width();
			if (realIconSize.height() < 0)
				realIconSize.height() = realImage->height();
		}
		if (font)
		{
			if (realIconSize.width() < 1)
				realIconSize.width() = font->size();
			if (realIconSize.height() < 1)
				realIconSize.height() = font->size();
		}
		alignment.ia_iconSize = realIconSize;
	}
	else
	{
		alignment.ia_iconSize.reset();
	}
	BRect crect = boss->centerRect();
	alignment.adjust(crect);
}
void member_BButton::popupMenu()
{
	menu->flush();
	BPoint offset = menu->offset();
	BSize size = menu->sizeHint();
	BRect rootRect = boss->mapFrom(boss->root(), boss->root()->size());
	BRect rect = boss->size();
	int x = rect.align(menu->align(), size).x();
	menu->setPos(x + offset.x(), rect.bottom() + offset.y());

	if (rootRect.bottom() - rect.bottom() < size.height())
	{
		menu->setPos(x + offset.x(), rect.top() - size.height() - offset.y());
	}

	menu->setSize(size);
	menu->setParent(boss);
	menu->popup();
}
void member_BButton::doclick()
{
	if (checkable)
	{
		checked = !checked;
		boss->emit(Signal_Checked, checked);
		boss->emit(Signal_Toggled, checked);
		boss->fresh();
	}
	if (action && action->enabled())
	{
		action->trigger();
	}
	if (menu && menu->enabled())
	{
		if (menu->visible())
		{
			menu->hide();
		}
		else
		{
			menu->flush();
			popupMenu();
		}
	}
}

void member_BButton::slotActionAbleChanged(BObject* object, const BValue& value)
{
	if (action == object)
	{
		boss->setEnabled(action->enabled());
	}
}
void member_BButton::slotActionIconChanged(BObject* object, const BValue& value)
{
	if (action == object)
	{
		dirty = true;
		boss->adjust();
	}
}
void member_BButton::slotActionTextChanged(BObject* object, const BValue& value)
{
	if (action == object)
	{
		dirty = true;
		boss->adjust();
	}
}
void member_BButton::slotActionChecked(BObject* object, const BValue& value)
{
	if (action == object)
	{
		if (!checkable)
			boss->setCheckable(true);
		checked = value;
		boss->emit(Signal_Checked, checked);
		boss->fresh();
	}
}

void member_BButton::slotMenuHide(BObject* object, const BValue& value)
{

}
void member_BButton::slotMenuEnabledChanged(BObject* object, const BValue& value)
{
	boss->setEnabled(object->enabled());
}
void member_BButton::slotMenuIconChanged(BObject* object, const BValue& value)
{
	if (menu == object)
	{
		dirty = true;
		boss->adjust();
	}
}
void member_BButton::slotMenuTitleChanged(BObject* object, const BValue& value)
{
	if (menu == object)
	{
		dirty = true;
		boss->adjust();
	}
}
void member_BButton::slotMenuStyleChanged(BObject* object, const BValue& value)
{
	if (menu == object)
	{
		dirty = true;
		boss->adjust();
	}
}

void member_BButton::slotShortcutTriggered(BObject* object, const BValue& value)
{
	boss->click();
}
